package com.icloud.system.boot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icloud.common.core.api.ResultCode;
import com.icloud.common.web.dto.CommonPageDto;
import com.icloud.common.web.exception.Asserts;
import com.icloud.system.boot.dao.AdminPermissionDao;
import com.icloud.system.boot.dao.AdminRoleDao;
import com.icloud.system.boot.dto.AdminRoleSaveDto;
import com.icloud.system.boot.mapper.AdminRoleMapper;
import com.icloud.system.boot.model.AdminPermission;
import com.icloud.system.boot.model.AdminRole;
import com.icloud.system.boot.model.AdminRolePermissionRelation;
import com.icloud.system.boot.model.AdminUserAuth;
import com.icloud.system.boot.service.AdminPermissionService;
import com.icloud.system.boot.service.AdminRolePermissionRelationService;
import com.icloud.system.boot.service.AdminRoleService;
import com.icloud.system.boot.service.AdminUserAuthService;
import com.icloud.system.boot.vo.AdminRoleDetailVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * 后台角色service实现类
 */

@Service
public class AdminRoleServiceImpl extends ServiceImpl<AdminRoleMapper, AdminRole> implements AdminRoleService {


    @Autowired
    private AdminPermissionDao adminPermissionDao;
    @Autowired
    private AdminUserAuthService adminUserAuthService;
    @Autowired
    private AdminRolePermissionRelationService adminRolePermissionRelationService;
    @Autowired
    private AdminPermissionService adminPermissionService;
    @Autowired
    private AdminRoleDao adminRoleDao;


    /**
     * 分页查询角色列表
     */
    @Override
    public IPage<AdminRole> getRolePageList(String name, CommonPageDto dto) {
        //分页
        Page<AdminRole> page = new Page<>(dto.getCurrent(), dto.getPageSize());
        //构造查询条件
        LambdaQueryWrapper<AdminRole> lqw = new LambdaQueryWrapper<>();
        lqw.like(StrUtil.isNotBlank(name), AdminRole::getName, name);
        //排序
        lqw.orderByAsc(AdminRole::getSortValue);
        return page(page, lqw);
    }


    /**
     * 添加角色
     */
    @Override
    public void addRole(AdminRoleSaveDto dto) {
        //参数校验
        AdminRoleSaveDto afterValidateDto = this.validateRole(null, dto);
        //数据插入
        AdminRole role = new AdminRole();
        BeanUtil.copyProperties(afterValidateDto, role);
        save(role);
    }

    /**
     * 角色参数校验
     */
    private AdminRoleSaveDto validateRole(Long id, AdminRoleSaveDto dto) {
        //验证数据是否存在
        long existCount = count(
                new LambdaQueryWrapper<AdminRole>().eq(AdminRole::getName, dto.getName()).ne(id != null, AdminRole::getId, id)
        );
        Asserts.fail(existCount > 0, ResultCode.DATA_EXISTS);
        return dto;
    }


    /**
     * 编辑角色
     */
    @Override
    public void updateRole(Long roleId, AdminRoleSaveDto dto) {
        //参数校验
        AdminRoleSaveDto afterValidateDto = this.validateRole(roleId, dto);
        //数据更新
        AdminRole role = getById(roleId);
        Asserts.fail(null == role,ResultCode.DATA_NOT_EXISTS);

        BeanUtil.copyProperties(afterValidateDto, role);
        updateById(role);
    }


    /**
     * 获取角色详情
     */
    @Override
    public AdminRoleDetailVo getRoleDetailById(Long roleId) {
        //获取角色
        AdminRole role = getById(roleId);
        if(null == role) {
            Asserts.fail(ResultCode.DATA_NOT_EXISTS);
        }
        //获取角色对应的权限ID集合
        List<Long> permissionIds = adminPermissionDao.getPermissionIdsByRoleId(roleId);
        AdminRoleDetailVo vo = new AdminRoleDetailVo();
        BeanUtil.copyProperties(role, vo);
        vo.setPermissionIds(permissionIds);
        return vo;
    }


    /**
     * 删除角色
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(Long roleId) {
        //删除账号角色关系数据
        LambdaUpdateWrapper<AdminUserAuth> updateWrapper = new LambdaUpdateWrapper<AdminUserAuth>().eq(AdminUserAuth::getAdminRoleId, roleId);
        AdminUserAuth adminUserAuth = new AdminUserAuth();
        adminUserAuth.setAdminRoleId(null);
        adminUserAuthService.update(adminUserAuth,updateWrapper);

        //删除角色权限关系数据
        adminRolePermissionRelationService.remove(new LambdaQueryWrapper<AdminRolePermissionRelation>().eq(AdminRolePermissionRelation::getAdminRoleId, roleId));
        //删除数据
        removeById(roleId);
        //同步权限角色对应关系到redis
        adminPermissionService.initPermissionRolesMap();
    }


    /**
     * 获取所有角色
     */
    @Override
    public List<AdminRole> getAllRole() {
        return list(new LambdaQueryWrapper<AdminRole>().orderByAsc(AdminRole::getSortValue));
    }


    /**
     * 给角色分配权限
     */
    @Override
    public void allocPermissions(Long roleId, List<Long> permissionIds) {
        if(CollUtil.isEmpty(permissionIds)) {
            Asserts.fail(ResultCode.VALIDATE_FAILED);
        }
        //校验权限参数是否有效
        long queryPermissionsCount = adminPermissionService.count(
                new LambdaQueryWrapper<AdminPermission>().in(AdminPermission::getId, permissionIds)
        );
        Asserts.fail(queryPermissionsCount != permissionIds.size(),ResultCode.VALIDATE_FAILED);

        //先删除原有关系
        adminRolePermissionRelationService.remove(new LambdaQueryWrapper<AdminRolePermissionRelation>().eq(AdminRolePermissionRelation::getAdminRoleId, roleId));
        //批量插入新关系
        List<AdminRolePermissionRelation> list = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for (Long permissionId : permissionIds) {
            AdminRolePermissionRelation relation = new AdminRolePermissionRelation();
            relation.setAdminRoleId(roleId);
            relation.setAdminPermissionId(permissionId);
            relation.setCreatedAt(now);
            relation.setUpdatedAt(now);
            list.add(relation);
        }
        adminRoleDao.batchInsertRolePermissions(list);
        //同步权限角色对应关系到redis
        adminPermissionService.initPermissionRolesMap();
    }
}
